| [ Return to Bugs & Features | Roadmap 1.1 | SVN ⇄ GIT ]
STR #1228
Application: | FLTK Library |
Status: | 1 - Closed w/Resolution |
Priority: | 2 - Low, e.g. a documentation error or undocumented side-effect |
Scope: | 2 - Specific to an operating system |
Subsystem: | Core Library |
Summary: | Fl_Help_View isspace() promotes "char" to "int" resulting in unwanted sign-extension |
Version: | 1.1.7 |
Created By: | jedimasterthrash |
Assigned To: | matt |
Fix Version: | 1.1-current (SVN: v5005) |
Update Notification: | |
Trouble Report Files:
No files
Trouble Report Comments:
|
#1 | jedimasterthrash 05:47 Apr 04, 2006 |
| In FLTK 1.1.6, Fl_Help_View.cxx line 970:
// Handle preformatted text... while (isspace(*ptr)) {
ptr is type "char", and isspace() takes type "int". Not sure about GCC, but the MSVC7 (.NET) compiler is performing a sign-extension. So all characters greater than or equal to 0x80 become 0xffffff80, and the msvcr71d.dll throws an assertion error when it detects a character greater than 255(decimal).
I caught this bug because my .html file I was viewing in the Help_View had some of everyone's favorite MS Word smart apostrophes. The smart apostrophe has some weird code, but it included a 0x92 character, and this character got sign-extended to 0xffffff92, and isspace in the VC7 runtime threw an exception for the character being >= 255.
As a solution on my end, I made sure to find and remove all those lovely smart apostrophes and use real apostrophes instead.
But I suggest looking up all the isspace calls and make sure you cast the character to an unsigned char to prevent it from being sign extended.
You can't cast it to an unsigned int though, because there's that "flaw" in the design of C type conversions where char is sign extended when converting to an unsigned int.
char c = 0x92; int i = c; //get 0xffffff92 int j = (unsigned char)c; //get 0x00000092 int k = (unsigned int)c; //get 0xffffff92
Since I've never encountered this isspace assertion until I compiled my program on MSVC.Net, I'm assuming it's something new/unique to its isspace implementation. It's possible that if I was running without the assertions turned on, it would if just displayed the bad character as a square [] like it's supposed to. So I doubt a release version would have crashed.
Thanks. | |
|
#2 | mike 15:09 Apr 04, 2006 |
| First, please test and report against the current release, as many times these bugs have already been fixed...
That said, we'll want to add &255 to each of the isspace calls, not cast to uchar, because the sign extension will have already occurred before the cast (the dereferencing has precedence) and we want an int. | |
|
#3 | jedimasterthrash 07:11 Apr 05, 2006 |
| I installed 1.1.7 and the problem still exists.
You're right about dereferencing the pointer, but I don't understand why it works that way.
char *ptr; int i = (unsigned int)*p;
In my opinion, the dereference or a char* should result in a "char", and then the char is cast to a uint.
However, in reality, the dereference results in auto-promoting the char to a signed int, and then the cast to a uint does nothing useful.
I'm not sure why the compiler works in this way. Probably something with a default in the language to auto-promote everything to ints in an expression.
Anyway, &255 works as you mentioned. Also, the isspace routine is called in several other files, including: fluid\CodeEditor.cxx fluid\file.cxx fluid\Fl_Function_Type.cxx fluid\Fl_Type.cxx fluid\Fl_Widget_Type.cxx fluid\fluid.cxx src\fl_draw.cxx src\fl_draw_pixmap.cxx src\Fl_File_Chooser2.cxx src\Fl_File_Icon2.cxx src\Fl_Help_View.cxx src\Fl_Input_.cxx src\Fl_Pixmap.cxx src\Fl_Text_Buffer.cxx src\Fl_Text_Display.cxx
Thanks, Ash. | |
|
#4 | matt 20:21 Apr 19, 2006 |
| Fixed in Subversion repository. | |
[ Return to Bugs & Features ]
|
| |